package cn.edu.dgut.css.sai.security.oauth2.client.userinfo;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequestEntityConverter;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.Collections;

/**
 * 码云 OAuth2 登录时使用的 OAuth2UserService
 *
 * @author sai
 * @since 2.2
 */
final class SaiGiteeOAuth2UserService extends DefaultOAuth2UserService {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        setRequestEntityConverter(this::createGiteeOAuth2UserServiceUserInfoRequestEntityConverter);
        return super.loadUser(userRequest);
    }

    /**
     * @see DefaultOAuth2UserService
     * @see OAuth2UserRequestEntityConverter
     */
    private RequestEntity<?> createGiteeOAuth2UserServiceUserInfoRequestEntityConverter(OAuth2UserRequest userRequest) {
        ClientRegistration clientRegistration = userRequest.getClientRegistration();
        URI uri = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUri())
                .queryParam("access_token", userRequest.getAccessToken().getTokenValue())
                .build()
                .toUri();
        return RequestEntity.get(uri).headers(getDefaultTokenRequestHeaders()).build();// get请求
    }

    /**
     * 码云的所有 openAPI 请求的header如果没有User-Agent会报错。
     * 码云官方issues: https://gitee.com/oschina/git-osc/issues/IDBSA
     */
    private HttpHeaders getDefaultTokenRequestHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        // 模拟构造一个User-Agent的header,发挥你的想象。
        headers.put("User-Agent", Collections.singletonList("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"));
        return headers;
    }
}
